/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.server.modules.sys.web.customer.impt;

import com.server.common.config.Global;
import com.server.common.persistence.Page;
import com.server.common.utils.PathUtils;
import com.server.common.utils.StringUtils;
import com.server.common.utils.excel.ExportExcel;
import com.server.common.web.BaseController;
import com.server.modules.sys.common.StaticDefine;
import com.server.modules.sys.entity.customer.export.CustomerExportLog;
import com.server.modules.sys.entity.customer.impt.CustomerImport;
import com.server.modules.sys.service.customer.export.CustomerExportLogService;
import com.server.modules.sys.service.customer.impt.CustomerImportLogService;
import com.server.modules.sys.service.customer.impt.CustomerImportService;
import com.server.modules.sys.utils.MyFileUtils;
import com.server.modules.sys.utils.date.DateUtil;
import com.server.modules.sys.zbus.IConsumerUtilService;
import com.server.modules.sys.zbus.IProducerUtilsService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static java.lang.System.out;

/**
 * 客户导入Controller
 * @author 丁光彪
 * @version 2016-10-28
 */
@Controller
@RequestMapping(value = "${adminPath}/sys/customer/impt/customerImport")
public class CustomerImportController extends BaseController {

	@Autowired
	private CustomerImportService customerImportService;
	
	@Autowired
	private CustomerImportLogService customerImportLogService;
	
	@Autowired
	private IConsumerUtilService consumerUtilService;
	
	@Autowired
	private IProducerUtilsService producerUtilsService;

	@Autowired
	private CustomerExportLogService customerExportLogService;
	
	/**
	 * 日志对象
	 */
	protected static Logger logger = LoggerFactory.getLogger(MyFileUtils.class);
	
	@ModelAttribute
	public CustomerImport get(@RequestParam(required=false) String id) {
		CustomerImport entity = null;
		if (StringUtils.isNotBlank(id)){
			entity = customerImportService.get(id);
		}
		if (entity == null){
			entity = new CustomerImport();
		}
		return entity;
	}
	
	/*@RequiresPermissions("sys:customer.impt:customerImport:view")*/
	@RequestMapping(value = {"list", ""})
	public String list(CustomerImport customerImport, HttpServletRequest request, HttpServletResponse response, Model model) {
		Page<CustomerImport> page = customerImportService.findPage(new Page<CustomerImport>(request, response), customerImport); 
		model.addAttribute("page", page);
		model.addAttribute("customerImport", customerImport);
		return "modules/sys/customer/impt/customerImportList";
	}

	/*@RequiresPermissions("sys:customer.impt:customerImport:view")*/
	@RequestMapping(value = "form")
	public String form(CustomerImport customerImport, Model model) {
		model.addAttribute("customerImport", customerImport);
		return "modules/sys/customer/impt/customerImportForm";
	}

	/*@RequiresPermissions("sys:customer.impt:customerImport:edit")*/
	@RequestMapping(value = "save")
	public String save(CustomerImport customerImport, Model model, RedirectAttributes redirectAttributes) {
		if (!beanValidator(model, customerImport)){
			return form(customerImport, model);
		}
		customerImportService.save(customerImport);
		addMessage(redirectAttributes, "保存客户导入成功");
		return "redirect:"+Global.getAdminPath()+"/sys/customer/impt/customerImport/?repage";
	}
	
	/*@RequiresPermissions("sys:customer.impt:customerImport:edit")*/
	@RequestMapping(value = "delete")
	public String delete(CustomerImport customerImport, RedirectAttributes redirectAttributes) {
		customerImportService.delete(customerImport);
		addMessage(redirectAttributes, "删除客户导入成功");
		return "redirect:"+Global.getAdminPath()+"/sys/customer/impt/customerImport/?repage";
	}

	@RequestMapping(value = "importBox")
	public String importBox(CustomerImport customerImport, Model model) {
		model.addAttribute("customerImport", customerImport);
		return "modules/sys/customer/impt/importBox";
	}
	/**
	 * 下载导入客户数据模板
	 * @param response
	 * @param redirectAttributes
	 * @return
	 */
	//@RequiresPermissions("sys:user:view")
    @RequestMapping(value = "import/template")
    public Object importFileTemplate(HttpServletResponse response,String type, RedirectAttributes redirectAttributes) {
		try {
			 String fileName = "";
			 String[] header = null;
			switch (type) {
			case StaticDefine.CUSTOMER_IMPORT_TYPE.car:
				fileName="车辆客户数据导入模板.xlsx";
				header=StaticDefine.CUSTOMER_IMPORT_TYPE_EXCEL_HEADER.car;
				break;
			case StaticDefine.CUSTOMER_IMPORT_TYPE.house:
				fileName="房产客户数据导入模板.xlsx";
				header=StaticDefine.CUSTOMER_IMPORT_TYPE_EXCEL_HEADER.house;
				break;
			case StaticDefine.CUSTOMER_IMPORT_TYPE.other:
				fileName="信息不全客户数据导入模板.xlsx";
				header=StaticDefine.CUSTOMER_IMPORT_TYPE_EXCEL_HEADER.other;
				break;
			default:
				break;
			}
			List<String> template=new ArrayList<>();
    		return new ExportExcel(null,header ).setDataList(template).write(response, fileName).dispose();
		} catch (Exception e) {
			addMessage(redirectAttributes, "导入模板下载失败！失败信息："+e.getMessage());
		}
		return null;
    }
    
    /**
	 * 导入客户数据
	 * @param file
	 * @param redirectAttributes
	 * @return
	 */
    @RequestMapping(value = "import", method=RequestMethod.POST)
    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes, HttpServletRequest request) {
		if(Global.isDemoMode()){
			addMessage(redirectAttributes, "演示模式，不允许操作！");
			return "redirect:" + adminPath + "/sys/customer/impt/customerImport?repage";
		}
		try {
			Map<String, Object> ret = customerImportService.batchInsert(file);
			Object failureMsg = ret.get("failureMsg");
			Object successNum = ret.get("successNum");
			addMessage(redirectAttributes, "已成功导入 "+successNum.toString()+" 条客户"+failureMsg.toString());
		} catch (Exception e) {
			e.printStackTrace();
			addMessage(redirectAttributes, "导入客户失败！失败信息："+e.getMessage());
		}
		return "redirect:" + adminPath + "/sys/customer/impt/customerImport?repage";
    }
   /* @RequestMapping(value = "startFileTodbMq", method=RequestMethod.POST)
    @ResponseBody
    public Object startFileTodbMq( RedirectAttributes redirectAttributes) throws IOException, InterruptedException {
    	// String path="/var/data";
    	   String path="d:\\test";
    	//  File file=new File(path);
    	  List<File> readfile = MyFileUtils.readfile(path,null);
    	  int size = readfile.size();
    	  System.out.println("该目录下对象个数："+size);
    		  for (int i = 0; i < size; i++) {
    			  File file3 = readfile.get(i);
    			  try {
		   	    	   if (file3.isFile()) {
		   	    		   int countByMd5 = customerImportLogService.countByMd5(Md5Utils.getFileMD5(file3));
		   	    		   if(countByMd5<1){
		   	    			   producerUtilsService.produceAnalyzeExcelFile(file3);
		   	    			   consumerUtilService.consumerImportInDbList();
		   	    		   }
		   	    	   }
		   	    	   if (file3.isDirectory()) {
		   	    		  // System.out.println("文件夹："+file3);
		   	    	   }
   			  } catch (Exception e) {
   					e.printStackTrace();
   			}
       	  }
    	return true;
    }*/
    
    @RequestMapping(value = "startFileTodbMq", method=RequestMethod.POST)
    @ResponseBody
    public Object startFileTodbMq( RedirectAttributes redirectAttributes) throws IOException, InterruptedException {
		//	String path="/var/data";
		String path=PathUtils.getPropertiesKeyValue("application.properties","import.path");
    	//  File file=new File(path);
    	  List<File> readfile = MyFileUtils.readfile(path,null);
		Collections.sort(readfile, new Comparator<File>(){
			public int compare(File o1, File o2) {
				//按文件大小升序排列
				if(o1.length() > o2.length()){
					return 1;
				}
				if(o1.length() == o2.length()){
					return 0;
				}
				return -1;
			}
		});


    	  int size = readfile.size();
    	  out.println("该目录下对象个数："+size);
			if (size > 10000) {
				  out.println("三个线程去执行："+size);
				List<File> subList1 = readfile.subList(0, 51);
				List<File> subList2 = readfile.subList(51, 100);
				List<File> subList3 = readfile.subList(100, readfile.size());
			new myThread(StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_INDB_MQ+"THREAD1",subList1).start();
				new myThread(StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_INDB_MQ+"THREAD2",subList2).start();
				new myThread(StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_INDB_MQ+"THREAD3",subList3).start();
			} else if (size > 5000) {
				out.println("2个线程去执行："+size);
				List<File> subList1 = readfile.subList(0, 51);
				List<File> subList2 = readfile.subList(51, readfile.size());
				new myThread(StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_INDB_MQ+"THREAD1",subList1).start();
				new myThread(StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_INDB_MQ+"THREAD2",subList2).start();
			}else{
				  out.println("1个线程去执行："+size);
				new myThread(StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_INDB_MQ+"THREAD1",readfile).start();
			}
			//线程太多会内存溢出
      //  new myThread(StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_INDB_MQ+"THREAD1",readfile).start();
    	return true;
    }
    
    class myThread extends Thread {
    	private String name;
    	private List<File> list;
    	public myThread(String Mqname,List<File> list) {
    		this.name=Mqname;
    		this.list=list;
    	}
    	@Override
    	public void run() {
    		 for (int i = 0; i < list.size(); i++) {
   			  File file3 = list.get(i);
   			  try {
		   	    	   if (file3.isFile()) {
		   	    		   /*int countByMd5 = customerImportLogService.countByMd5(Md5Utils.getFileMD5(file3));
		   	    		   if(countByMd5<1){*/
							   customerImportService.batchInsert(file3);
                           /*   *//* consumerUtilService.consumerImportInDbList(name);
		   	    			   producerUtilsService.produceAnalyzeExcelFile(file3,name);*//*
		   	    		   }else{

						   }*/
		   	    	   }
		   	    	   if (file3.isDirectory()) {
		   	    		  // System.out.println("文件夹："+file3);
		   	    	   }
  			  } catch (Exception e) {
  					e.printStackTrace();
  			}
    	}
    }
    }

	class myExportThread extends Thread {
		private List<CustomerExportLog> list;
		public myExportThread(List<CustomerExportLog> list) {
			this.list=list;
		}
		@Override
		public void run() {
				try {
					customerExportLogService.batchInsert(list);
				} catch (Exception e) {
					e.printStackTrace();
				}
		}
	}


	/**
	 * 导出用户数据
	 * @param num
	 * @return
	 */
    @RequestMapping(value = "export", method=RequestMethod.POST)
    public String exportFile(CustomerImport customerImport, HttpServletRequest request,HttpServletResponse response, Integer num,RedirectAttributes redirectAttributes) {
		try {
			Integer exportNum=num!=null?num:5000;
            customerImport.setPage(null);
            List<CustomerImport> list = customerImportService.findList(customerImport);
            List<HSSFWorkbook> hssfWorkbooks = customerExportLogService.data2excel(list, exportNum);
			Date currentDate=new Date();
            String yyyyMMdd = DateUtil.DateToString(currentDate, "yyyy年MM月dd日");
            int i=0;
            // 设置导出excel文件
            OutputStream out = response.getOutputStream();
            ZipOutputStream zipOutputStream = new ZipOutputStream(out);
            String fileName = "导出客户" +currentDate.getTime()+ ".zip";
            response.setContentType("application/octet-stream ");
            response.setHeader("Connection", "close"); // 表示不能用浏览器直接打开
            response.setHeader("Accept-Ranges", "bytes");// 告诉客户端允许断点续传多线程连接下载
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("GB2312"), "ISO8859-1"));
            response.setCharacterEncoding("UTF-8");
            for (HSSFWorkbook hssfWorkbook : hssfWorkbooks) {
                i++;
                ZipEntry entry = new ZipEntry(yyyyMMdd+"导出文件"+i+ ".xls");
                zipOutputStream.putNextEntry(entry);
                hssfWorkbook.write(zipOutputStream);
            }

			int size=list.size();
			List<CustomerExportLog> exportlist =new ArrayList<>();
			for (CustomerImport ci:list ) {
				CustomerExportLog export=new CustomerExportLog();
				export.setCustomerId(ci.getId());
				export.preInsert();
				exportlist.add(export);
			}
			if (size > 1000000) {
				System.out.println("四个线程去执行："+size);
				List<CustomerExportLog> subList1 = exportlist.subList(0, 250000);
				List<CustomerExportLog> subList2 = exportlist.subList(250001, 500000);
				List<CustomerExportLog> subList3 = exportlist.subList(500001, 750000);
				List<CustomerExportLog> subList4 = exportlist.subList(750001, size);
				new myExportThread(subList1).start();
				new myExportThread(subList2).start();
				new myExportThread(subList3).start();
				new myExportThread(subList4).start();
			} else if (size > 500000) {
				List<CustomerExportLog> subList1 = exportlist.subList(0, 250000);
				List<CustomerExportLog> subList2 = exportlist.subList(250001, 500000);
				List<CustomerExportLog> subList3 = exportlist.subList(500001, size);
				new myExportThread(subList1).start();
				new myExportThread(subList2).start();
				new myExportThread(subList3).start();
			}else if (size > 100000){
				List<CustomerExportLog> subList1 = exportlist.subList(0, 100000);
				List<CustomerExportLog> subList2 = exportlist.subList(100001, size);
				new myExportThread(subList1).start();
				new myExportThread(subList2).start();
			}else{
				new myExportThread(exportlist).start();
			}
            // 关闭输出流
            zipOutputStream.flush();
            zipOutputStream.close();

		} catch (Exception e) {
			e.printStackTrace();
			addMessage(redirectAttributes, "导出客户失败！失败信息："+e.getMessage());
		}
        return "redirect:" + adminPath + "/sys/customer/impt/customerImport?repage";
    }
    @RequestMapping(value = {"printPage"})
	public String printPage(CustomerImport customerImport, HttpServletRequest request, HttpServletResponse response, Model model) {
		model.addAttribute("list", customerImportService.findList(customerImport));
		customerImport.setPage(null);
		model.addAttribute("customerImport", customerImport);
		return "modules/sys/customer/impt/customerImportList_print";
	}
    
    @RequestMapping(value = {"test"})
    @ResponseBody
   	public Object test(CustomerImport customerImport, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
   		return "modules/sys/customer/impt/customerImportList_print";
   	}

	@RequestMapping(value = {"isMd5Exist"})
	@ResponseBody
	public Object isMd5Exist(String md5, HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
		return customerImportLogService.countByMd5(md5)>0?true:false;
	}
   	
	

}